package com.yc.cloud.admin.service.impl;

import com.yc.cloud.admin.dto.UmsMenuNode;
import com.yc.cloud.entity.UmsMenu;
import com.yc.cloud.mapper.UmsMenuMapper;
import com.yc.cloud.admin.service.UmsMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.basic.dto.BaseQueryParam;
import lombok.val;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台菜单表 服务实现类
 * </p>
 *
 * @author JackGu
 * @since 2022-09-11
 */
@Service
public class UmsMenuServiceImpl extends ServiceImpl<UmsMenuMapper, UmsMenu> implements UmsMenuService {

    @Resource
    private UmsMenuMapper umsMenuMapper;

    @Override
    public IPage<UmsMenu> list(BaseQueryParam queryParam) {
        val query = new QueryWrapper<UmsMenu>();
        IPage<UmsMenu> page;
        //排序
        if (StrUtil.isNotEmpty(queryParam.getSortBy())) {
            if (BaseQueryParam.ORDER_DESC.equals(queryParam.getOrder())) {
                query.orderByDesc(UmsMenu.ID);
            } else if (BaseQueryParam.ORDER_ASC.equals(queryParam.getOrder())) {
                query.orderByAsc(UmsMenu.ID);
            }
        }
        //模糊查询
        if (StrUtil.isNotEmpty(queryParam.getKeyword())) {
            query.and(queryWrapper -> {

            });
        }
        //分页
        if (queryParam.getPage()) {
            page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize(), true);
        } else {
            page = new Page<>(queryParam.getPageNum(), umsMenuMapper.selectCount(query), true);
        }
        return umsMenuMapper.selectPage(page, query);
    }

    @Override
    public List<UmsMenu> getMenuList(Long adminId) {
        return umsMenuMapper.getMenuList(adminId);
    }

    @Override
    public IPage<UmsMenu> list(Long parentId, Integer pageSize, Integer pageNum) {
        QueryWrapper<UmsMenu> query = new QueryWrapper<>();
        query.eq("parent_id", parentId);
        IPage<UmsMenu> page = new Page<>(pageNum, pageSize, true);
        return umsMenuMapper.selectPage(page, query);
    }

    @Override
    public List<UmsMenu> queryByLevel(Integer level) {
        return umsMenuMapper.selectList(new QueryWrapper<UmsMenu>().eq(UmsMenu.LEVEL, level));
    }

    @Override
    public int create(UmsMenu umsMenu) {
        umsMenu.setCreateTime(LocalDateTime.now());
        updateLevel(umsMenu);
        return umsMenuMapper.insert(umsMenu);
    }

    @Override
    public List<UmsMenuNode> treeList() {
        List<UmsMenu> menuList = umsMenuMapper.selectList(new QueryWrapper<>());
        List<UmsMenuNode> result = menuList.stream()
                .filter(menu -> menu.getParentId().equals(0L))
                .map(menu -> covertMenuNode(menu, menuList)).collect(Collectors.toList());
        return result;
    }

    @Override
    public List<UmsMenu> queryByRoleId(Long roleId) {
        return umsMenuMapper.queryByRoleId(roleId);
    }

    /**
     * 修改菜单层级
     */
    private void updateLevel(UmsMenu umsMenu) {
        if (umsMenu.getParentId() == 0) {
            //没有父菜单时为一级菜单
            umsMenu.setLevel(0);
        } else {
            //有父菜单时选择根据父菜单level设置
            UmsMenu parentMenu = umsMenuMapper.selectById(umsMenu.getParentId());
            if (parentMenu != null) {
                umsMenu.setLevel(parentMenu.getLevel() + 1);
            } else {
                umsMenu.setLevel(0);
            }
        }
    }

    /**
     * 将UmsMenu转化为UmsMenuNode并设置children属性
     */
    private UmsMenuNode covertMenuNode(UmsMenu menu, List<UmsMenu> menuList) {
        UmsMenuNode node = new UmsMenuNode();
        BeanUtils.copyProperties(menu, node);
        List<UmsMenuNode> children = menuList.stream()
                .filter(subMenu -> subMenu.getParentId().equals(menu.getId()))
                .map(subMenu -> covertMenuNode(subMenu, menuList)).collect(Collectors.toList());
        node.setChildren(children);
        return node;
    }
}
